#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
智能出行规划HTTP服务器
集成多式联运、智能中转、全局优化功能
"""

import http.server
import socketserver
import json
import urllib.parse
from urllib.parse import urlparse, parse_qs
import webbrowser
import os
import requests
from datetime import datetime, timedelta

# 导入智能规划器
from smart_travel_planner import SmartTravelPlanner, OptimizationType

# 导入其他API
try:
    from simple_railway_api import RailwayAPI
except Exception:
    RailwayAPI = None

try:
    from api_keys_complete import DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, DEEPSEEK_MODEL
except Exception:
    DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL, DEEPSEEK_MODEL = None, None, None

try:
    from backend.gaode_api import GaodeAPI
except Exception:
    GaodeAPI = None

try:
    from api_keys_complete import GAODE_API_KEY as GAODE_KEY
except Exception:
    try:
        from api_keys import GAODE_API_KEY as GAODE_KEY
    except Exception:
        GAODE_KEY = None

# 可选：使用openai官方客户端兼容DeepSeek
try:
    import openai
    OpenAIClient = openai.OpenAI
except Exception:
    OpenAIClient = None

# 初始化组件
_railway_api = RailwayAPI() if RailwayAPI else None
_gaode_api = GaodeAPI(GAODE_KEY) if (GaodeAPI and GAODE_KEY) else None
_smart_planner = SmartTravelPlanner()

PORT = 5000

class SmartHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        static_root = os.path.dirname(__file__)
        super().__init__(*args, directory=static_root, **kwargs)
    def do_GET(self):
        # 将根路径映射到前端页面
        if self.path in ['/', '/index', '/index.html']:
            self.path = '/frontend/index.html'
        elif self.path == '/favicon.ico':
            return self.send_error(404)
        if self.path.startswith('/api/'):
            self.handle_api_request()
        else:
            super().do_GET()
    
    def do_POST(self):
        if self.path.startswith('/api/'):
            self.handle_api_post()
        else:
            super().do_POST()
    
    def do_OPTIONS(self):
        # 处理CORS预检请求
        self.send_response(200)
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        self.send_header('Access-Control-Max-Age', '86400')
        self.end_headers()
    
    def handle_api_request(self):
        if self.path == '/api/cities':
            self.send_cities()
        elif self.path == '/api/test':
            self.send_test()
        elif self.path == '/api/status':
            self.send_status()
        elif self.path.startswith('/api/weather'):
            self.send_weather()
        else:
            self.send_error(404)
    
    def handle_api_post(self):
        content_length = int(self.headers.get('Content-Length', 0) or 0)
        post_data = self.rfile.read(content_length) if content_length > 0 else b'{}'
        
        try:
            data = json.loads(post_data.decode('utf-8') or '{}')
            if self.path == '/api/search':
                self.send_smart_search_result(data)
            elif self.path == '/api/chat':
                self.send_chat_response(data)
            elif self.path == '/api/poi':
                self.send_poi(data)
            elif self.path == '/api/geocode':
                self.send_geocode(data)
            elif self.path == '/api/weather':
                self.send_weather(data)
            else:
                self.send_error(404)
        except Exception as e:
            self.send_json_response({'success': False, 'error': f'请求解析失败: {e}'})
    
    def send_cities(self):
        cities = [
            '北京', '上海', '广州', '深圳', '南京', '杭州',
            '成都', '武汉', '西安', '重庆', '天津', '苏州',
            '大连', '合肥', '青岛', '济南', '沈阳', '长沙'
        ]
        response = {
            'success': True,
            'cities': [{'id': i + 1, 'name': c, 'code': '', 'level': 'city'} for i, c in enumerate(cities)]
        }
        self.send_json_response(response)
    
    def send_test(self):
        response = {
            'success': True,
            'message': '智能出行规划服务器正常运行！',
            'features': [
                '多式联运规划',
                '智能中转建议', 
                '全局优化排序',
                '实时交通数据'
            ]
        }
        self.send_json_response(response)
    
    def send_status(self):
        response = {
            'success': True,
            'status': 'online',
            'version': '2.0.0',
            'apis': {
                'gaode': 'available' if _gaode_api else 'mock',
                'railway': 'available' if _railway_api else 'mock',
                'ai': 'available' if (DEEPSEEK_API_KEY and DEEPSEEK_BASE_URL and DEEPSEEK_MODEL) else 'mock',
                'smart_planner': 'enabled',
                'multimodal': 'enabled',
                'transfer_optimization': 'enabled'
            }
        }
        self.send_json_response(response)
    
    def send_smart_search_result(self, data):
        """智能搜索主函数"""
        origin = data.get('origin', '北京')
        destination = data.get('destination', '上海')
        date = data.get('date') or data.get('departure_date')
        optimization_type = data.get('optimization_type', 'balanced')
        max_transfers = data.get('max_transfers', 2)
        time_window = data.get('time_window')  # (earliest, latest)
        
        print(f"🎯 智能搜索请求: {origin} → {destination} ({date})")
        
        try:
            # 转换优化类型
            opt_type = OptimizationType.BALANCED
            if optimization_type == 'time':
                opt_type = OptimizationType.TIME
            elif optimization_type == 'cost':
                opt_type = OptimizationType.COST
            elif optimization_type == 'comfort':
                opt_type = OptimizationType.COMFORT
            
            # 调用智能规划器
            routes = _smart_planner.find_routes(
                origin=origin,
                destination=destination,
                date=date,
                optimization=opt_type,
                max_transfers=max_transfers,
                time_window=time_window
            )
            
            # 转换为前端格式
            formatted_routes = []
            for route in routes:
                formatted_route = {
                    'total_time': route.total_time,
                    'total_price': route.total_cost,
                    'total_distance': route.total_distance,
                    'transfers': route.transfers,
                    'comfort_score': route.comfort_score,
                    'reliability_score': route.reliability_score,
                    'optimization_score': route.optimization_score,
                    'tags': route.tags,
                    'description': route.description,
                    'details': []
                }
                
                # 转换交通段详情
                for leg in route.legs:
                    detail = {
                        'type': leg.mode.value,
                        'origin': leg.origin,
                        'destination': leg.destination,
                        'departure_time': leg.departure_time,
                        'arrival_time': leg.arrival_time,
                        'duration': leg.duration,
                        'price': leg.price,
                        'distance': leg.distance,
                        'comfort_score': leg.comfort_score,
                        'reliability_score': leg.reliability_score,
                        'transfer_time': leg.transfer_time,
                        'transfer_cost': leg.transfer_cost
                    }
                    
                    # 添加交通方式特定信息
                    if leg.mode.value == 'flight':
                        detail['flight_number'] = leg.details.get('flight_number', '') if leg.details else ''
                        detail['airline'] = leg.details.get('airline', '') if leg.details else ''
                    elif leg.mode.value in ['high_speed_rail', 'train']:
                        detail['train_number'] = leg.details.get('train_number', '') if leg.details else ''
                        detail['seat_type'] = leg.details.get('seat_type', '') if leg.details else ''
                    
                    formatted_route['details'].append(detail)
                
                formatted_routes.append(formatted_route)
            
            response = {
                'success': True,
                'routes': formatted_routes,
                'message': f'智能规划为您找到 {len(formatted_routes)} 条最优路线',
                'source': 'smart_planner',
                'optimization_type': optimization_type,
                'params': {
                    'origin': origin,
                    'destination': destination,
                    'date': date,
                    'max_transfers': max_transfers,
                    'time_window': time_window
                }
            }
            
            self.send_json_response(response)
            
        except Exception as e:
            print(f"智能搜索失败: {e}")
            self.send_json_response({
                'success': False,
                'error': f'智能规划失败: {e}',
                'routes': [],
                'message': '搜索失败，请重试'
            })
    
    def send_weather(self, data=None):
        """天气查询"""
        if data:
            city = data.get('city', '北京')
        else:
            query_params = parse_qs(urlparse(self.path).query)
            city = query_params.get('city', ['北京'])[0]
        
        try:
            if _gaode_api:
                weather_data = _gaode_api.get_weather(city)
                response = {
                    'success': True,
                    'weather': weather_data,
                    'source': 'gaode'
                }
            else:
                # 模拟天气数据
                response = {
                    'success': True,
                    'weather': {
                        'city': city,
                        'temperature': '22°C',
                        'condition': '多云',
                        'humidity': '65%',
                        'wind': '东南风 3级'
                    },
                    'source': 'mock'
                }
        except Exception as e:
            response = {
                'success': False,
                'error': f'天气查询失败: {e}',
                'source': 'error'
            }
        
        self.send_json_response(response)
    
    def send_poi(self, data):
        """POI搜索"""
        query = data.get('query', '')
        city = data.get('city', '北京')
        
        try:
            if _gaode_api:
                pois = _gaode_api.search_poi(query, city)
                response = {
                    'success': True,
                    'pois': pois,
                    'source': 'gaode'
                }
            else:
                # 模拟POI数据
                response = {
                    'success': True,
                    'pois': [
                        {'name': f'{query}示例地点1', 'address': f'{city}市示例地址1', 'location': '116.397,39.916'},
                        {'name': f'{query}示例地点2', 'address': f'{city}市示例地址2', 'location': '116.407,39.926'}
                    ],
                    'source': 'mock'
                }
        except Exception as e:
            response = {
                'success': False,
                'error': f'POI搜索失败: {e}',
                'source': 'error'
            }
        
        self.send_json_response(response)
    
    def send_geocode(self, data):
        """地理编码"""
        address = data.get('address', '')
        
        try:
            if _gaode_api:
                result = _gaode_api.geocode(address)
                response = {
                    'success': True,
                    'geocode': result,
                    'source': 'gaode'
                }
            else:
                # 模拟地理编码数据
                response = {
                    'success': True,
                    'geocode': {
                        'address': address,
                        'location': '116.397,39.916',
                        'formatted_address': f'{address}（模拟地址）'
                    },
                    'source': 'mock'
                }
        except Exception as e:
            response = {
                'success': False,
                'error': f'地理编码失败: {e}',
                'source': 'error'
            }
        
        self.send_json_response(response)
    
    def send_chat_response(self, data):
        """AI聊天回复"""
        message = data.get('message', '')
        if not message:
            self.send_json_response({'success': False, 'error': '请提供message'})
            return
        
        tz_offset = data.get('timezoneOffsetMinutes') or data.get('timezone_offset')
        
        # 本地时间问题优先用用户本地时间直接回答
        if self._is_time_query(message):
            now_text = self._format_now(tz_offset)
            self.send_json_response({'success': True, 'response': f'现在是 {now_text}（您的本地时间）', 'model': 'builtin'})
            return
        
        # 调用DeepSeek AI
        try:
            ai_response = self._deepseek_chat(message, tz_offset)
            if ai_response.get('success'):
                self.send_json_response({
                    'success': True,
                    'response': ai_response['response'],
                    'model': 'deepseek'
                })
            else:
                # 降级到简单回复
                self.send_json_response({
                    'success': True,
                    'response': f'我理解您的问题："{message}"。作为智能出行助手，我可以帮您规划最优路线、查询交通信息、提供出行建议。请告诉我您的具体需求！',
                    'model': 'fallback'
                })
        except Exception as e:
            self.send_json_response({
                'success': True,
                'response': f'抱歉，AI服务暂时不可用。但我可以帮您规划出行路线！请使用搜索功能查询从出发地到目的地的交通方案。',
                'model': 'error_fallback'
            })
    
    def _is_time_query(self, text: str) -> bool:
        if not text:
            return False
        keywords = ['现在几点', '几点了', '几点', '时间', '日期', '今天几号', '几月几号', '今天星期', '星期几', '今天是几号']
        return any(k in text for k in keywords)
    
    def _format_now(self, tz_offset_minutes=None):
        if tz_offset_minutes is None:
            return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        try:
            local_time = datetime.utcnow() - timedelta(minutes=int(tz_offset_minutes))
            return local_time.strftime('%Y-%m-%d %H:%M:%S')
        except Exception:
            return datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    
    def _deepseek_chat(self, message, tz_offset_minutes=None):
        server_now = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        user_now = self._format_now(tz_offset_minutes)
        system_prompt = (
            f"你是一个专业的智能出行规划助手，请用简洁的中文回复。"
            f"当前服务器时间：{server_now}；用户本地时间：{user_now}。"
            f"你可以帮助用户规划最优出行路线、查询交通信息、提供出行建议。"
            f"回答涉及时间问题时，请以用户本地时间为准。"
        )
        
        if DEEPSEEK_API_KEY and DEEPSEEK_BASE_URL and DEEPSEEK_MODEL and OpenAIClient:
            try:
                client = OpenAIClient(api_key=DEEPSEEK_API_KEY, base_url=DEEPSEEK_BASE_URL)
                resp = client.chat.completions.create(
                    model=DEEPSEEK_MODEL,
                    messages=[
                        {"role": "system", "content": system_prompt},
                        {"role": "user", "content": message}
                    ],
                    max_tokens=300,
                    temperature=0.7
                )
                return {
                    'success': True,
                    'response': resp.choices[0].message.content
                }
            except Exception as e:
                pass
        
        # 降级到HTTP直连
        if DEEPSEEK_API_KEY and DEEPSEEK_BASE_URL and DEEPSEEK_MODEL:
            try:
                url = f"{DEEPSEEK_BASE_URL.rstrip('/')}/chat/completions"
                headers = {
                    'Authorization': f'Bearer {DEEPSEEK_API_KEY}',
                    'Content-Type': 'application/json'
                }
                payload = {
                    'model': DEEPSEEK_MODEL,
                    'messages': [
                        {"role": "system", "content": system_prompt},
                        {"role": "user", "content": message}
                    ],
                    'max_tokens': 300,
                    'temperature': 0.7
                }
                r = requests.post(url, headers=headers, json=payload, timeout=15)
                j = r.json()
                if 'choices' in j and j['choices']:
                    content = j['choices'][0].get('message', {}).get('content', '')
                    if content:
                        return {'success': True, 'response': content}
                return {'success': False, 'error': f'DeepSeek HTTP错误: {j}'}
            except Exception as e:
                return {'success': False, 'error': f'DeepSeek直连失败: {e}'}
        
        return {'success': False, 'error': 'DeepSeek未配置或依赖缺失'}
    
    def send_json_response(self, data):
        """发送JSON响应"""
        self.send_response(200)
        self.send_header('Content-Type', 'application/json; charset=utf-8')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        
        json_str = json.dumps(data, ensure_ascii=False, indent=2)
        self.wfile.write(json_str.encode('utf-8'))

if __name__ == '__main__':
    print("=" * 60)
    print("启动智能出行规划服务器")
    print("=" * 60)
    print(f"服务地址: http://localhost:{PORT}")
    print(f"测试地址: http://localhost:{PORT}/api/test")
    print(f"城市列表: http://localhost:{PORT}/api/cities")
    print(f"前端页面: http://localhost:{PORT}/frontend/index.html")
    print("=" * 60)
    print("按 Ctrl+C 停止服务")
    print("=" * 60)
    
    with socketserver.TCPServer(("", PORT), SmartHTTPRequestHandler) as httpd:
        try:
            # 自动打开浏览器
            webbrowser.open(f"http://localhost:{PORT}/frontend/index.html")
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\n服务器已停止")